/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.googlecode.jsimplemarket.service;

import com.googlecode.jsimplemarket.model.RaportIncasari;
import com.googlecode.jsimplemarket.model.TotalIncasari;
import com.googlecode.jsimplemarket.repository.InchiriereRepository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * @author Alexandru.Codescu
 */
@Service(value = "inchiriereService")
public class InchiriereService {
    @Autowired
    private InchiriereRepository inchiriereRepository;
    
    private Date getDataInceputZi(Date data) {
        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        gregorianCalendar.setTime(data);
        gregorianCalendar.set(GregorianCalendar.HOUR, 0);
        gregorianCalendar.set(GregorianCalendar.MINUTE, 0);
        gregorianCalendar.set(GregorianCalendar.SECOND, 0);
        gregorianCalendar.set(GregorianCalendar.AM_PM, GregorianCalendar.AM);
        return gregorianCalendar.getTime();
    }
    
    private Date getDataSfarsitZi(Date data) {
        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        gregorianCalendar.setTime(data);
        gregorianCalendar.set(GregorianCalendar.AM_PM, GregorianCalendar.PM);
        gregorianCalendar.set(GregorianCalendar.HOUR, 11);
        gregorianCalendar.set(GregorianCalendar.MINUTE, 59);
        gregorianCalendar.set(GregorianCalendar.SECOND, 59);
        return gregorianCalendar.getTime();
    }
    
    private Date getDataSfarsit(Date dataInceput, int interval) {
        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        gregorianCalendar.setTime(dataInceput);
        gregorianCalendar.add(GregorianCalendar.DATE, interval);
        
        return gregorianCalendar.getTime();
    }
 
    
    
    private GregorianCalendar getTodayCalendar() {
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.set(GregorianCalendar.HOUR_OF_DAY, 0);
        calendar.set(GregorianCalendar.MINUTE, 0);
        calendar.set(GregorianCalendar.SECOND, 0);
        //calendar.set(GregorianCalendar.AM_PM, GregorianCalendar.AM);
        calendar.set(GregorianCalendar.MILLISECOND, 0);
        return calendar;
    }
    
    private Date getTodayDate() {
        return getTodayCalendar().getTime();
    }
    
    private Date addDays(Date date, int days) {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.add(Calendar.DATE, days);
                 
        return cal.getTime();
    }
    
    private Date get7DayDate() {
        GregorianCalendar calendar = getTodayCalendar();
        calendar.add(GregorianCalendar.DATE, -7);
        
        return calendar.getTime();
    }
    
    private Date getFirstDayOfMonth() {
        GregorianCalendar calendar = getTodayCalendar();
        //comment next line for current month
        calendar.add(GregorianCalendar.MONTH, 1);
        calendar.set(GregorianCalendar.DATE, 1); //first day of the next month
        
        return calendar.getTime();
    }
    
    private Date getLastDayOfMonth() {
        GregorianCalendar calendar = getTodayCalendar();
      //comment next line for current month
        calendar.add(GregorianCalendar.MONTH, 1);
        calendar.set(GregorianCalendar.DATE, 
        		calendar.getActualMaximum(GregorianCalendar.DAY_OF_MONTH)); //last day of the next month
        
        return calendar.getTime();
    }
    

    
    
    private Date getTomorrowCalendar() {
    	GregorianCalendar calendar = getTodayCalendar();
        calendar.add(GregorianCalendar.DATE, 1);        
        return calendar.getTime();
    }
    
    
    private Date getLastMonthDate() {
        GregorianCalendar calendar = getTodayCalendar();
        calendar.set(GregorianCalendar.DATE, 1);
        
        return calendar.getTime();
    }
    
    public List<RaportIncasari> queryIncasariByData(Date data) {
        Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        
        List<Object[]> incasari = inchiriereRepository.queryIncasariByData(dataInceput, dataSfarsit);
        List<RaportIncasari> rapoarteIncasari = new ArrayList<RaportIncasari>(incasari.size());
        
        for (Object[] incasare : incasari) {
            RaportIncasari raport = new RaportIncasari();
            raport.setDenumireTaxa(incasare[0].toString());
            raport.setValoareTaxa((BigDecimal) incasare[1]);
            raport.setNrSpatii((Long) incasare[2]);
            raport.setValoareTotala(raport.getValoareTaxa().multiply(new BigDecimal(raport.getNrSpatii())));
            
            rapoarteIncasari.add(raport);
        }
        
        return rapoarteIncasari;
    }
    
    public List<TotalIncasari> queryTotalIncasariByData(Date data) {
        Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        
        List<Object[]> vanzari = inchiriereRepository.querySumIncasariByData(dataInceput, dataSfarsit);
        List<TotalIncasari> totalIncasari = new ArrayList<TotalIncasari>(vanzari.size());
        
        
        for (Object[] vanzare : vanzari) {
        	TotalIncasari total = new TotalIncasari();
        	total.setValoareTotala((BigDecimal) vanzare[0]);
        	total.setTotalSpatii((Long) vanzare[1]);
                        
        	totalIncasari.add(total);
        }
        
        return totalIncasari;
    }

    public List<Object[]> queryTarabeByData(Date data) {
        Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        return inchiriereRepository.queryTarabeByData(dataInceput, dataSfarsit);
    }
    
    public List<Object[]> queryTarabeByDataAA(Date data) {
        Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        return inchiriereRepository.queryTarabeByDataAA(dataInceput, dataSfarsit);
    }
    
    
    public List<Object[]> queryInchirieriByTarabaByDay(Date data, Long idTaraba) {
        Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        return inchiriereRepository.queryInchirieriByTarabaByDay(dataInceput, dataSfarsit, idTaraba);
    }
    
    public List<Object[]> queryIncasariByDataPlata(Date data) {
        Date dataStart = getDataInceputZi(data);
        //Date dataSfarsit = getDataSfarsitZi(data);
        return inchiriereRepository.queryIncasariByDataPlata(dataStart);
    }
    
    public List<Object[]> queryIncasariByDataPlataDetailed(Date data) {
        Date dataStart = getDataInceputZi(data);
        //Date dataSfarsit = getDataSfarsitZi(data);
        return inchiriereRepository.queryIncasariByDataPlataDetailed(dataStart);
    }
    
//    public Object[] queryIncasariByDataPlata(Date data) {
//        Date dataStart = getDataInceputZi(data);
//        //Date dataSfarsit = getDataSfarsitZi(data);
//        List<Object[]> objs = inchiriereRepository.queryIncasariByDataPlata(dataStart);
//        if (objs.isEmpty()) {
//            return null;
//        } else {
//            return objs.get(0);
//        }
//    }
    
    
    public Object[] queryFirmaByTaraba(Long idTaraba, Date data) {
    	Date dataStart = getLastMonthDate();
    	Date dataSfarsit = getDataInceputZi(data);
        //Date dataSfarsit = getDataSfarsitZi(data);
    	
    	
        List<Object[]> objs = inchiriereRepository.queryFirmaByTaraba(idTaraba,dataStart,dataSfarsit);
        if (objs.isEmpty()) {
                return null;
            } else {
                return objs.get(0);
            }
    }
    
    public Object[] querySumIncasariByData(Date data) {
    	Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        
        List<Object[]> vanzari = inchiriereRepository.querySumIncasariByData(dataInceput, dataSfarsit);
        if (vanzari.isEmpty()) {
            return null;
        } else {
            return vanzari.get(0);
        }
    }
    
    public List<Object[]> querySumIncasariByDataTZ(Date data) {
    	Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        
        return inchiriereRepository.querySumIncasariByDataTZ(dataInceput, dataSfarsit);
        
    }
    
    public List<Object[]> querySumIncasariByDataAA(Date data) {
    	Date dataInceput = getDataInceputZi(data);
        Date dataSfarsit = getDataSfarsitZi(data);
        
        return inchiriereRepository.querySumIncasariByDataAA(dataInceput, dataSfarsit);
        
    }
    
    public List<Object[]> queryTotalIncasariByDataPlata(Date data) {
    	Date dataInceput = getDataInceputZi(data);
        //Date dataSfarsit = getDataSfarsitZi(data);        
        return inchiriereRepository.querySumIncasariByDataPlata(dataInceput);
    }
}
